<?php
/**
 * 字符工具类
 */

namespace common\utils;


class XString
{
    /**
     * @param int $length
     * @return string 随机生成小写的英文字母
     */
    public static function ranStr($length = 4)
    {
        $str = '';
        for ($i = 0; $i < $length; $i++) {
            $str .= chr(rand(97, 122));
        }
        return $str;
    }

    /**
     * @param int $length
     * @return string 随机字符串
     */
    public static function randomkeys($length)
    {
        $key = '';
        $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ';
        for ($i = 0; $i < $length; $i++) {
            $key .= $pattern{mt_rand(0, 35)};
        }
        return $key;
    }

    /**
     * @param int $length
     * @return string 随机数
     */
    public static function randomnum($length)
    {
        $pattern = '1234567890';
        $key = "";
        for ($i = 0; $i < $length; $i++) {
            $key .= $pattern{mt_rand(0, 9)};
        }
        return $key;
    }

    /**
     * @param string $str
     * @return bool 验证邮箱
     */
    public static function email($str)
    {
        if (empty($str))
            return true;
        $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
        if (strpos($str, '@') !== false && strpos($str, '.') !== false) {
            if (preg_match($chars, $str)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 根据生日时间戳计算年龄
     * @param int $birthday 生日时间戳
     * @return int 年龄
     */
    public static function getAge($birthday)
    {
        $age = date('Y', time()) - date('Y', $birthday);
        if (date('m', time()) == date('m', $birthday)) {
            if (date('d', time()) > date('d', $birthday)) {
                $age++;
            }
        } elseif (date('m', time()) > date('m', strtotime($birthday))) {
            $age++;
        }
        return $age;
    }

    /**
     * 格式化秒
     * @param int $time 秒
     * @return string  时间格式化
     */
    public static function formatTime($time)
    {
        $output = '';
        foreach (array(86400 => '天', 3600 => '小时', 60 => '分', 1 => '秒') as $key => $value) {
            if ($time >= $key) $output .= floor($time / $key) . $value;
            $time %= $key;
        }
        return $output;
    }

    /**
     * @param int $time 时间戳
     * @return string 格式化时间
     */
    public static function timeTran($time)
    {
        $dur = time() - $time;
        if ($dur < 0) {
            return $time;
        } else {
            if ($dur < 60) {
                if ($dur == 0) {
                    return '刚刚';
                } else {
                    return $dur . '秒前';
                }
            } else {
                if ($dur < 3600) {
                    return floor($dur / 60) . '分钟前';
                } else {
                    if ($dur < 86400) {
                        return floor($dur / 3600) . '小时前';
                    } else {
                        if ($dur < 259200) {//3天内
                            return floor($dur / 86400) . '天前';
                        } else {
                            return date('Y-m-d', $time);
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取毫秒级时间戳
     * @return float 毫秒级时间戳
     */
    public static function getMillisecond()
    {
        list($usec, $sec) = explode(' ', microtime());
        return ((float)$usec + (float)$sec);
    }

    /**
     * 格式化时间戳，精确到毫秒，x代表毫秒
     * @param $tag
     * @param null $time
     * @return mixed
     */
    public static function microtimeFormat($tag, $time = null)
    {
        if (!$time) {
            $time = static::getMillisecond();
        }
        list($usec, $sec) = explode(".", $time);
        if (strlen($sec) > 4) {
            $sec = substr($sec, 0, 4);
        }
        $date = date($tag, $usec);
        return str_replace('x', $sec, $date);
    }

    /**
     * 字符截取
     * @param string $string
     * @param int $length
     * @param string $dot
     * @param string $charset
     * @return string
     */
    public static function cutStr($string, $length, $dot = '...', $charset = 'utf-8')
    {
        if (strlen($string) <= $length)
            return $string;

        $pre = chr(1);
        $end = chr(1);
        $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end), $string);

        $strcut = '';
        if (strtolower($charset) == 'utf-8') {
            $n = $tn = $noc = 0;
            while ($n < strlen($string)) {
                $t = ord($string[$n]);
                if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                    $tn = 1;
                    $n++;
                    $noc++;
                } elseif (194 <= $t && $t <= 223) {
                    $tn = 2;
                    $n += 2;
                    $noc += 2;
                } elseif (224 <= $t && $t <= 239) {
                    $tn = 3;
                    $n += 3;
                    $noc += 2;
                } elseif (240 <= $t && $t <= 247) {
                    $tn = 4;
                    $n += 4;
                    $noc += 2;
                } elseif (248 <= $t && $t <= 251) {
                    $tn = 5;
                    $n += 5;
                    $noc += 2;
                } elseif ($t == 252 || $t == 253) {
                    $tn = 6;
                    $n += 6;
                    $noc += 2;
                } else {
                    $n++;
                }
                if ($noc >= $length) {
                    break;
                }
            }
            if ($noc > $length) {
                $n -= $tn;
            }
            $strcut = substr($string, 0, $n);
        } else {
            for ($i = 0; $i < $length; $i++) {
                $strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i];
            }
        }
        $strcut = str_replace(array($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);
        $pos = strrpos($strcut, chr(1));
        if ($pos !== false) {
            $strcut = substr($strcut, 0, $pos);
        }
        return $strcut . $dot;
    }

    /**
     * 去字符串中的 HTML、XML 以及 PHP的标签格式化
     * @param string $subject
     * @param int $length
     * @param string $dot
     * @param string $charset
     * @return mixed
     */
    public static function clearCutStr($subject, $length = 0, $dot = '...', $charset = 'utf-8')
    {
        $hr = DIRECTORY_SEPARATOR == '\\' ? "\r\n" : "\n";
        if ($length) {
            return static::cutStr(strip_tags(str_replace([$hr], '', $subject)), $length, $dot, $charset);
        } else {
            return strip_tags(str_replace([$hr], '', $subject));
        }
    }

    /**
     * 去字符串中的 HTML、XML 以及 PHP的标签包括空格格式化
     * @param $subject
     * @param int $length
     * @param string $dot
     * @param string $charset
     * @return string
     */
    public static function clearCutStrWithSpace($subject, $length = 0, $dot = '...', $charset = 'utf-8')
    {
        $hr = DIRECTORY_SEPARATOR == '\\' ? "\r\n" : "\n";
        $subject = str_replace("&nbsp;", "", str_replace("	", "", $subject));
        if ($length) {
            return static::cutStr(strip_tags(str_replace([$hr], '', $subject)), $length, $dot, $charset);
        } else {
            return strip_tags(str_replace([$hr], '', $subject));
        }
    }
}